#include "wthread.h"
#include <QDir>
#include <QMessageBox>
#include <QDesktopServices>
#include <QUrl>
#include <QHeaderView>
#include <QMetaType>
#include <QStringList>
#include <QtCore>
#include "xlsxformat.h"
#include "xlsxdocument.h"
#include "xlsxformat.h"
#include "xlsxcellrange.h"
#include "xlsxchart.h"
#include "qt_windows.h"

enum {
    IMPORT,
    EXPORT,
    EXPORTAREACHANNEL,
    IDLE
};
enum {
    wOK,
    wEMPTY,
    wINFORMAT,
    wINITERROR
};

wThread::wThread(QObject *parent) : QThread(parent)
{
    flag = IDLE;
    qRegisterMetaType<QVector<int>>("QVector<int>");
}

void wThread::setImport()
{
    flag = IMPORT;
}

void wThread::setExport()
{
    flag = EXPORT;
}

void wThread::setExportAreaChannel()
{
    flag = EXPORTAREACHANNEL;
}

void wThread::recvPara(QTableWidget *t,QTableWidget *at,QStringList header,QStringList areahead,QMap<int,CHANNINFO> *cha)
{
    table = t;
    areatable = at;
    headers = header;
    areaheaders = areahead;
    channels = *cha;
}

void wThread::recvParaAreaChannel(QTableWidget *t,QMap<int,CHANNINFO> *map, QString path)
{
    Areatable = t;
    channelmap = map;
    Areafilepath = path;
}

void wThread::recvAreaTable(QTableWidget *t,QStringList head)
{
    Areatable = t;
    areaheaders = head;
    qDebug() << "recvAreaTable" << areaheaders.size();
}

void wThread::getExportfilepath(QString path)
{
    filename = path;
}

void wThread::getImportfilepath(QString path)
{
     importfilePath = path;
}

void wThread::Table2Excel(QTableWidget *table,QString fileName)
{

        if (fileName!="")
        {
            QAxObject *excel = new QAxObject;
            if (excel->setControl("Excel.Application")) //连接Excel控件
            {
                excel->dynamicCall("SetVisible (bool Visible)","false");//不显示窗体
                excel->setProperty("DisplayAlerts", false);//不显示任何警告信息。如果为true那么在关闭是会出现类似“文件已修改，是否保存”的提示
                QAxObject *workbooks = excel->querySubObject("WorkBooks");//获取工作簿集合
                workbooks->dynamicCall("Add");//新建一个工作簿
                QAxObject *workbook = excel->querySubObject("ActiveWorkBook");//获取当前工作簿
                QAxObject *worksheet = workbook->querySubObject("Worksheets(int)", 1);
                int i,j,colcount=table->columnCount();
                QAxObject *cell,*col;
                //标题行
//                cell=worksheet->querySubObject("Cells(int,int)", 1, 1);
//                cell->dynamicCall("SetValue(const QString&)", title);
//                cell->querySubObject("Font")->setProperty("Size", 18);
                //调整行高
//                worksheet->querySubObject("Range(const QString&)", "1:1")->setProperty("RowHeight", 30);
                //合并标题行
                QString cellTitle;
//                cellTitle.append("A1:");
//                cellTitle.append(QChar(colcount - 1 + 'A'));
 //               cellTitle.append(QString::number(1));
 //              QAxObject *range = worksheet->querySubObject("Range(const QString&)", cellTitle);
 //               range->setProperty("WrapText", true);
 //               range->setProperty("MergeCells", true);
 //               range->setProperty("HorizontalAlignment", -4108);//xlCenter
  //              range->setProperty("VerticalAlignment", -4108);//xlCenter
                //列标题
                for(i=0;i<colcount;i++)
                {
                    QString columnName;
                    columnName.append(QChar(i  + 'A'));
                    columnName.append(":");
                    columnName.append(QChar(i + 'A'));
                    col = worksheet->querySubObject("Columns(const QString&)", columnName);
                    col->setProperty("ColumnWidth", table->columnWidth(i)/6);
                    cell=worksheet->querySubObject("Cells(int,int)", 1, i+1);
                    columnName=table->horizontalHeaderItem(i)->text();
                    cell->dynamicCall("SetValue(const QString&)", columnName);
                    cell->querySubObject("Font")->setProperty("Bold", true);
                    cell->querySubObject("Interior")->setProperty("Color",QColor(191, 191, 191));
                    cell->setProperty("HorizontalAlignment", -4108);//xlCenter
                    cell->setProperty("VerticalAlignment", -4108);//xlCenter
                }
                //数据区
                for(i=0;i<table->rowCount();i++){
                    for (j=0;j<colcount;j++)
                    {
                        worksheet->querySubObject("Cells(int,int)", i+2, j+1)->dynamicCall("SetValue(const QString&)", table->item(i,j)?table->item(i,j)->text():"");
                    }
                }
                //画框线
                QString lrange;
                lrange.append("A1:");
                lrange.append(colcount - 1 + 'A');
                lrange.append(QString::number(table->rowCount() + 2));
       //         range = worksheet->querySubObject("Range(const QString&)", lrange);
      //          range->querySubObject("Borders")->setProperty("LineStyle", QString::number(1));
      //          range->querySubObject("Borders")->setProperty("Color", QColor(0, 0, 0));
                //调整数据区行高
                QString rowsName;
                rowsName.append("1:");
                rowsName.append(QString::number(table->rowCount() + 1));
                //range = worksheet->querySubObject("Range(const QString&)", rowsName);
                //range->setProperty("RowHeight", 20);
                workbook->dynamicCall("SaveAs(const QString&)",QDir::toNativeSeparators(fileName));//保存至fileName
                workbook->dynamicCall("Close()");//关闭工作簿
                excel->dynamicCall("Quit()");//关闭excel
                delete excel;
                excel=NULL;
                //if (QMessageBox::question(NULL,"finish","The file has been exported, open it now？",QMessageBox::Yes|QMessageBox::No)==QMessageBox::Yes)
                //{
                //    QDesktopServices::openUrl(QUrl("file:///" + QDir::toNativeSeparators(fileName)));
                //}
                emit export_ok();
            }
            else
            {
                //QMessageBox::warning(NULL,"ERR","Failed to create Excel object, please install Microsoft Excel。",QMessageBox::Apply);
                emit export_failed1();
            }
        }

}

void wThread::ExportAreaChannel(QTableWidget *table,QMap<int,CHANNINFO> map,QString fileName)
{

        if (fileName!="")
        {
            //qDebug() <<fileName;

            QXlsx::Document xlsx(fileName);/*打开一个book1的文件*/

            QXlsx::Format format;/*设置该单元的样式*/
            format.setBorderColor(QColor("#000000"));

            format.setFontSize(11);/*设置字体大小*/

            format.setVerticalAlignment(QXlsx::Format::AlignVCenter);
            format.setHorizontalAlignment(QXlsx::Format::AlignHCenter);/*横向居中*/

            xlsx.write("A1", "No");
            xlsx.write("B1", "ZoneArea");
            xlsx.write("C1", "ChannelList");


            int col = table->columnCount();
            int row = table->rowCount();


            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    QString str = table->item(i,j)->text();//取出字符串
                    char ch = 'A' + j;
                    QString index = QString("%1%2").arg(ch).arg(i+2);
                    xlsx.write(index, str);
                }
            }

            if(!xlsx.selectSheet("Sheet2")){/*在当前打开的xlsx文件中，找一个名字为ziv的sheet*/
                xlsx.addSheet("Sheet2");//找不到的话就添加一个名为ziv的sheet
            }

            QString ctitile = "No#AreaNo#Channel Name#Channel Type#TX Freq#RF Freq#Color Code/Bandwidth#Power#Channel Mode/RX CTCSS Type#Call Type/RX CTCSS Code#Output Timeslot/TX CTCSS Type#Input Timeslot/TX CTCSS Code#Volume#Mic Gain/Mute#Local ID#Contact Num#Encrypt#Encrypt Key#Group List";
            QStringList clist = ctitile.split("#");
            qDebug() << "clist.size() = " <<clist.size();
            for (int i = 0; i < clist.size(); i++) {
                char ch = 'A' + i;
                QString index = QString("%1%2").arg(ch).arg(1);
                xlsx.write(index, clist.at(i));
            }

            qDebug() << map.keys().size();

            QMap<int,CHANNINFO>::iterator item;
            int j = 0;

            for(item = map.begin(); item != map.end(); ++item,j++) {

                QStringList tmp = item.value().AreaID.split("#");

                QString tcalltype;
                QString tinput;
                //模拟信道需要转换
                if (item.value().ChannelType == "A"){
                    if (item.value().ChannelMode != "1")
                        tcalltype = value_to_index(item.value().ChannelMode,item.value().CallType);
                    else
                        tcalltype = "0";
                    if (item.value().OutputTimeslot != "1")
                        tinput = value_to_index(item.value().OutputTimeslot,item.value().InputTimeslot);
                    else
                         tinput = "0";
                }
                if (item.value().ChannelType == "D"){
                     tcalltype = item.value().CallType;
                     tinput = item.value().InputTimeslot;
                }

                QString str = tmp.at(1) + "#" + tmp.at(0) + "#"
                        + item.value().ChannelName + "#" + item.value().ChannelType + "#"
                        + item.value().TXFrequency + "#" + item.value().RXFrequency + "#"
                        + item.value().ColorCode + "#" + item.value().Power + "#"
                        + item.value().ChannelMode + "#" + tcalltype + "#"
                        + item.value().OutputTimeslot + "#" + tinput + "#"
                        + item.value().Volume + "#" + item.value().MicGain + "#" + item.value().Id + "#"
                        + item.value().num + "#" + item.value().encrypt + "#" + item.value().key + "#"
                        + item.value().list;
//                        + item.value().num + "#" + item.value().list + "#" + item.value().key + "#"
//                        + item.value().encrypt;

                QStringList list = str.split("#");
                qDebug() << "str = " <<str;


                for (int i = 0; i < list.size(); i++) {
                    char ch = 'A' + i;
                    QString index = QString("%1%2").arg(ch).arg(j+2);
                    xlsx.write(index, list.at(i));
                }
                //j++;

            }
            xlsx.saveAs(fileName);/*保存*/
             emit export_ok();

       }
}

int wThread::openExcel(QString fileName)
{
    int ret;
    HRESULT r = OleInitialize(0);
    if (r != S_OK && r != S_FALSE)
    {
        qDebug() << "OleInitialize error";
        ret = wINITERROR;
        return ret;
    }


    QAxObject excel("Excel.Application");
    excel.setProperty("Visible", false);
    QAxObject *work_books = excel.querySubObject("WorkBooks");
    work_books->dynamicCall("Open(const QString&)", fileName);

    QAxObject *work_book = excel.querySubObject("ActiveWorkBook");
    QAxObject *work_sheets = work_book->querySubObject("Sheets");  //Sheets也可换用WorkSheets

    int sheet_count = work_sheets->property("Count").toInt();  //获取工作表数目
    //qDebug() << "sheet_count = " << sheet_count;
    if (sheet_count > 0)
    {
        channels.clear();

        QAxObject *work_sheet = work_book->querySubObject("Sheets(int)", 2);
        QVariant var = readAll(work_sheet);
        ret = castVariant2ListListVariantchannel(table,headers,var);
        //table_init();
        qDebug() << "myy channels.keys().size() = " <<channels.keys().size();
        for (int i = 0; i < channels.keys().size(); i++)
        {
            qDebug() << channels.value(i).AreaID <<channels.value(i).CallType
                     << channels.value(i).ChannelMode << channels.value(i).ChannelName
                     << channels.value(i).ChannelType << channels.value(i).ColorCode;
        }


        QAxObject *work_sheet1 = work_book->querySubObject("Sheets(int)", 1);
        QVariant var1 = readAll(work_sheet1);
        ret = castVariant2ListListVariant(areatable,areaheaders,var1);

    }

    work_book->dynamicCall("Close(Boolean)", false);  //关闭文件
    excel.dynamicCall("Quit(void)");  //退出
    //ui->switch_file->setEnabled(true);
    //qDebug() << "ret = " <<ret;

    OleUninitialize();

    return ret;
}

void wThread::table_init()
 {
    table->clear();
    table->setColumnCount(0);
    table->setRowCount(0);

    Areatable->clear();
    Areatable->setColumnCount(0);
    Areatable->setRowCount(0);

    QString str = "No#Channel Name#Channel Type#TX Frequency#RX Frequency#Color Code/Bandwidth#Power#Channel Mode/RX CTCSS Type#Call Type/RX CTCSS Code#Output Timeslot/TX CTCSS Type#Input Timeslot/TX CTCSS Code#Volume#Mic Gain/Mute";
    headers = str.split("#");

    table->setColumnCount(headers.size()); //设置列数
    table->setHorizontalHeaderLabels(headers);

    for (int x = 0; x < headers.size(); x++)
        table->horizontalHeader()->setSectionResizeMode(x,QHeaderView::ResizeToContents);

    str = "No#AreaName#channelsize";
    areaheaders = str.split("#");

    Areatable->setColumnCount(areaheaders.size()); //设置列数
    Areatable->setHorizontalHeaderLabels(areaheaders);

    for (int x = 0; x < areaheaders.size(); x++)
        Areatable->horizontalHeader()->setSectionResizeMode(x,QHeaderView::ResizeToContents);

//    ui->areatable->setSelectionBehavior(QAbstractItemView::SelectRows); //设置选择行为，以行为单位
//    ui->areatable->setSelectionMode(QAbstractItemView::SingleSelection); //设置选择模式，选择单行

 }

int wThread::castVariant2ListListVariantchannel(QTableWidget *table,QStringList headers,const QVariant &var)
{
    QVariantList varRows = var.toList();
    if (varRows.isEmpty())
    {
        return wEMPTY;
    }

    const int rowCount = varRows.size();
    //qDebug()<<"================="<<rowCount;
    QVariantList rowData;
    for (int i = 0; i < rowCount; ++i)
    {
        //qDebug() << i;
        rowData = varRows[i].toList();
        if (i == 0)
        {
            QStringList header;
            foreach (auto item , rowData)
            {
                QString value = item.toString();
                header.append(value);
            }

            qDebug() << "header.size() = "<<header.size() << "headers.size() = " <<headers.size();
            if (header.size() < headers.size()) {

                for (int i = 0; i < header.size(); i++)
                    qDebug() << header.at(i);
                 return wINFORMAT;
            }
        }
        else
        {
            int j;
            for (j = 0; j < rowData.size(); j++) {
                if (!rowData[j].toString().isEmpty())
                    break;
            }

            if (j == rowData.size()) {
                //qDebug() << "跳过空行";
                continue;
            }

           //qDebug() << "读取数据";

            int row = table->rowCount();
            qDebug() <<row << rowData.size();
            table->setRowCount(row + 1);

            //for (int j = 0; j < rowData.size(); j++)
            {

//                qDebug() << "myy123" ;
//                qDebug() << QString("%1#%2#").arg(rowData[1].toString()).arg(rowData[0].toString());
//                 qDebug() << rowData[2].toString();
//                 qDebug() << rowData[3].toString();
//                 qDebug() << rowData[4].toString();
//                 qDebug() << rowData[5].toString();
//                 qDebug() << rowData[6].toString();
//                 qDebug() << rowData[7].toString();
//                 qDebug() << rowData[8].toString();
//                 qDebug() << rowData[9].toString();
//                 qDebug() << rowData[10].toString();
//                 qDebug() << rowData[11].toString();
//                 qDebug() << rowData[12].toString();
//                 qDebug() << rowData[13].toString();
//                 qDebug() << rowData[14].toString();


                CHANNINFO chaninfo;
                //chaninfo.AreaID = QString("%1#%2#").arg(rowData[1].toString()).arg(row+1);
                chaninfo.AreaID = QString("%1#%2#").arg(rowData[1].toString()).arg(rowData[0].toString());
                 chaninfo.ChannelName = rowData[2].toString();
                 chaninfo.ChannelType = rowData[3].toString();
                 chaninfo.TXFrequency = rowData[4].toString();
                 chaninfo.RXFrequency = rowData[5].toString();
                 chaninfo.ColorCode = rowData[6].toString();
                 chaninfo.Power = rowData[7].toString();
                 chaninfo.ChannelMode = rowData[8].toString();
                 chaninfo.CallType = rowData[9].toString();
                 chaninfo.OutputTimeslot = rowData[10].toString();
                 chaninfo.InputTimeslot = rowData[11].toString();
                 chaninfo.Volume = rowData[12].toString();
                 chaninfo.MicGain = rowData[13].toString();
                 chaninfo.Id = rowData[14].toString();
                 chaninfo.num = rowData[15].toString();
                 chaninfo.list = rowData[18].toString();
                 chaninfo.key = rowData[17].toString();
                 chaninfo.encrypt = rowData[16].toString();

                channels.insert(channels.keys().size(),chaninfo);

            }
        }
    }
    return wOK;
}

int wThread::castVariant2ListListVariant(QTableWidget *table,QStringList headers,const QVariant &var)
{
    QVariantList varRows = var.toList();
    if (varRows.isEmpty())
    {
        return wEMPTY;
    }

    const int rowCount = varRows.size();
    //qDebug()<<"================="<<rowCount;
    QVariantList rowData;
    for (int i = 0; i < rowCount; ++i)
    {
        //qDebug() << i;
        rowData = varRows[i].toList();
        if (i == 0)
        {
            QStringList header;
            foreach (auto item , rowData)
            {
                QString value = item.toString();
                header.append(value);
            }

            qDebug() << "header.size() = "<<header.size() << "headers.size() = " <<headers.size();
            if (header.size() < headers.size()) {

                for (int i = 0; i < header.size(); i++)
                    qDebug() << header.at(i);
                 return wINFORMAT;
            }

//            table->clear();
//            table->setColumnCount(0);
//            table->setRowCount(0);
//            table_init();

            //ui->tableWidget->setColumnCount(headers.size()); //设置列数
            //ui->tableWidget->setHorizontalHeaderLabels(headers);
//            for (int x = 0; x < headers.size(); x++)
//            ui->tableWidget->horizontalHeader()->setSectionResizeMode(x,QHeaderView::ResizeToContents);
//            ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

//            qDebug() <<"xxxxxxx";
//            for (int i; i < headers.size(); i++) {
//                //if (!header.at(i).contains(headers.at(i)) || !headers.at(i).contains(header.at(i)))
//                //    return INFORMAT;
//                if (header.at(i).contains(headers.at(i)))
//                    qDebug() <<"yes";
//            }
        }
        else
        {
            //qDebug() << "rowData.size() = " <<rowData.size();
            int j;
            for (j = 0; j < rowData.size(); j++) {
                if (!rowData[j].toString().isEmpty())
                    break;
            }

            if (j == rowData.size()) {
                //qDebug() << "跳过空行";
                continue;
            }

           //qDebug() << "读取数据";

            int row = table->rowCount();
            qDebug() <<row << rowData.size();
            table->setRowCount(row + 1);

            for (int j = 0; j < rowData.size(); j++)
            {
                QString value = rowData[j].toString();
                //qDebug() << value;
                QTableWidgetItem *item = new QTableWidgetItem(value);
                if (j == 0 || j == 2)
                    item->setFlags(item->flags() & (~Qt::ItemIsEditable));
                table->setItem(row, j, item);
                //ui->tableWidget->item(row,j)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);

            }
        }
    }

//    int col = ui->tableWidget->columnCount();
//    int row = ui->tableWidget->rowCount();
//    ui->tableWidget->insertRow(row);

//    for (int i = 0; i < col; i++) {
//        QString value = "";
//        QTableWidgetItem *item = new QTableWidgetItem(value);
//        ui->tableWidget->setItem(row, i, item);
//        ui->tableWidget->item(row,i)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);
//    }
//    file.close();
    //显示默认文件
    //ui->sendfile->setText(send_filename);
    return wOK;
}

QVariant wThread::readAll(QAxObject *sheet)
{
    QVariant var;
    if (sheet != NULL && !sheet->isNull())
    {
        QAxObject *usedRange = sheet->querySubObject("UsedRange");
        if (NULL == usedRange || usedRange->isNull())
        {
            return var;
        }
        var = usedRange->dynamicCall("Value");
        delete usedRange;
    }
    return var;
}


void wThread::recvQmap(QMap<int,CHANNINFO> *chan)
{
    channels = *chan;
}

void wThread::run()
{
    int ret;
    //while (1) {
        if (flag == EXPORT) {
            //Table2Excel(table,filename);
            ExportAreaChannel(areatable,channels,filename);
            flag = IDLE;
        }

        if (flag == IMPORT) {
            ret = openExcel(importfilePath);
            flag = IDLE;
            qDebug() << "读取完成，发送import_ret信号";
            emit import_ret(ret,&channels);
        }

        if (flag == EXPORTAREACHANNEL) {
            ExportAreaChannel(Areatable,*channelmap,Areafilepath);
            flag = IDLE;
        }
        sleep(1);
    //}
}

QString wThread::value_to_index(QString type,QString value)
{
    QString filename;
    if (type == "2") //如果是CTCSS,解析 cparallel table
    {
        filename = "./ShowInfo/cparallel.txt";
        qDebug() << "myy 解析cparallel.txt";
    }
    else if ((type == "3") || (type == "4")) //如果是CDCSS,解析CDCSS
    {
        filename = "./ShowInfo/cdcss.txt";
    }
    else
        return "Error";

    QFile file(filename);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        if (language == "English") {
            QString str = QString("open file[%1]feiled!").arg(filename);
            QMessageBox::warning(NULL, "prompt", str, "OK");
        }
        if (language == "Chinese") {
            QString str = QString("打开文件[%1]失败!").arg(filename);
            QMessageBox::warning(NULL, "提示", str, "确定");
        }
        return "Error";
    }
    while(!file.atEnd())
    {
        QByteArray line = file.readLine();
        QString str = QString(line);
        QStringList tmplist = str.split("#");
        QString tvalue = QString("%1").arg(tmplist.at(1));
        tvalue = tvalue.simplified();
        tvalue.replace(" ", "");

        if (tvalue == value) {
            qDebug() << "找到对应的索引为" << QString("%1").arg(tmplist.at(0));
            file.close();
            return QString("%1").arg(tmplist.at(0));
        }
    }

    file.close();
    return "Error";
}
